package com.mogu.biguser.shiro;

import com.mogu.biguser.common.constant.AuthConst;
import com.mogu.biguser.common.util.ShiroUtils;
import com.mogu.biguser.dao.base_sys.SysMenuMapper;
import com.mogu.biguser.dao.base_sys.SysUserMapper;
import com.mogu.biguser.domain.base_sys.SysMenu;
import com.mogu.biguser.domain.base_sys.SysUser;
import com.mogu.biguser.web.api.model.User;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;

/**
 * Created with IntelliJ IDEA
 *
 * @Author yuanhaoyue swithaoy@gmail.com
 * @Description 自定义 Realm
 * @Date 2018-03-25
 * @Time 21:46
 */
@Component
public class CustomRealm extends AuthorizingRealm {
   @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    private SysMenuMapper sysMenuMapper;

    /**
     * 获取身份验证信息
     * Shiro中，最终是通过 Realm 来获取应用程序中的用户、角色及权限信息的。
     *
     * @param authenticationToken 用户身份信息 token
     * @return 返回封装了用户信息的 AuthenticationInfo 实例
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("————身份认证方法————");


        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        String password = new String(token.getPassword());

        //查询用户信息
        User sysUser = sysUserMapper.selectNameByUserName(token.getUsername());
        SysUser user = sysUser.getSysUser();
        //账号不存在
        if(user == null) {
            throw new UnknownAccountException("账号或密码不正确");
        }else{
            ShiroKit.getSession().setAttribute("SysUser",user);
            String name = sysUser.getName();
            if(name ==null){
                name =user.getUsername();
            }
            ShiroKit.getSession().setAttribute("SysUserName",name);
            //下面这是获取数据权限方法
            Session session=ShiroKit.getSession();
            String token1=(String)session.getAttribute(AuthConst.TOKEN);
            int userId =Integer.valueOf(user.getUserId()+"");
            List<String> areaId=sysUserMapper.queryAllRegion(userId);
            List<String> deptId=sysUserMapper.queryAllRegiondeptId(userId);
            session.setAttribute(token1,areaId);
            session.setAttribute("depts",deptId);
        }

        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), ByteSource.Util.bytes(user.getSalt()), getName());
        return info;
    }

    /**
     * 获取授权信息
     *
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        System.out.println("————权限认证————");
        SysUser user = (SysUser)principals.getPrimaryPrincipal();
        ShiroKit.getSession().setAttribute("SysUser",user);
        int userId =Integer.valueOf(user.getUserId()+"");
        List<String> permsList = null;
        List<String> permsList1 = null;

        //系统管理员，拥有最高菜单权限
        if(userId == 1){
            List<SysMenu> menuList = sysMenuMapper.queryList(new HashMap<String, Object>());   //查询数据库sys_menu表获取字段perms的权限信息，是管理员获取全部
            permsList = new ArrayList<>(menuList.size());
            for(SysMenu menu : menuList){
                permsList.add(menu.getPerms());
            }
        }else{
            permsList = sysUserMapper.queryAllPerms(userId,11); //web  安全
//            permsList1 = sysUserMapper.queryAllPerms(userId,28);
//       permsList = sysUserMapper.queryAllPerms(userId,29);  //不是管理员则是获取当前系统的菜单权限， 数字2则是该系统的数字标识，在表sys_menu的basesysnum字段可看到app
//permsList.addAll(permsList1);
        }
        ShiroKit.getSession().setAttribute("permsList",permsList);
        //用户菜单权限列表
        Set<String> permsSet = new HashSet<String>();
        for(String perms : permsList){
            if(StringUtils.isBlank(perms)){
                continue;
            }

            permsSet.addAll(Arrays.asList(perms.trim().split(",")));
        }
        Session session=ShiroKit.getSession();
        String token1=(String)session.getAttribute(AuthConst.TOKEN);
        List<String> areaId=sysUserMapper.queryAllRegion(userId);
        List<String> deptId=sysUserMapper.queryAllRegiondeptId(userId);
        session.setAttribute(token1,areaId);
        session.setAttribute("depts",deptId);


        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        info.setStringPermissions(permsSet);
        System.err.println(permsSet);
        return info;}

    @Override
    public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
        HashedCredentialsMatcher shaCredentialsMatcher = new HashedCredentialsMatcher();
        shaCredentialsMatcher.setHashAlgorithmName(ShiroUtils.hashAlgorithmName);
        shaCredentialsMatcher.setHashIterations(ShiroUtils.hashIterations);
        super.setCredentialsMatcher(shaCredentialsMatcher);
    }

}

        /*String username = user.getUsername();
        principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        username="admin123";
        //获得该用户角色
        String role = sysUserMapper.getRole(username);
        Set<String> set = new HashSet<>();
        //需要将 role 封装到 Set 作为 info.setRoles() 的参数
        set.add(role);
        //设置该用户拥有的角色
        info.setRoles(set);
        return info;*/





